/*==============================================================================
**                                  LINDBOARD
**                      Proprietary - Copyright (C) 2014
**                      www.facebook.com/lindboard
**------------------------------------------------------------------------------
** Supported MCUs      : MCU STM32F10x
** Supported Compilers : KeilC
**------------------------------------------------------------------------------
** File name         : COM.c
**  
** Module name       : Character LCD Display
**
** Summary: Source file of LCD Display
**
**= History ===================================================================
** 00.00.01  17/7/2014  Cuong Chu
**           - Creation
==============================================================================*/
/******************************************************************************/
/* INCLUSIONS                                                                 */
/******************************************************************************/
#include "stm32f10x.h"
#include "bsp/output.h"
#include "lcd/lcd.h"
#include "tim/timer.h"
/*******************************************************************************/
/* DEFINITION OF MACROS                                                        */
/*******************************************************************************/
#define LCD_Delayms(x)     Timer_DelayMs(x) /* put delay function here */
/******************************************************************************/
/* DEFINITION OF LOCAL VARIABLE                                               */
/******************************************************************************/
static const uint8_t MaskBit[] = {0x80,0x40,0x20,0x10};
static const uint8_t ShiftBit[] = {0x07,0x06,0x05,0x04};
/******************************************************************************/
/* DEFINITION OF CONSTANTS                                                    */
/******************************************************************************/
#define NULL_PTR ((void *)0)

/******************************************************************************/
/* DEFINITION OF GLOBAL FUNCTIONS                                             */
/******************************************************************************/
/*******************************************************************************
** Function name: LCD_StartDisplay( void  )
** Description  : The function starting display          
** Parameter    : none
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
void LCD_StartDisplay
(
  void
)
{
  /* init io pin control */
  OUTPUT_IOEnableClock();
  /* init ouput control pin */
  OUTPUT_OutputInit(OUT_LCD_D0);
  OUTPUT_OutputInit(OUT_LCD_D1);
  OUTPUT_OutputInit(OUT_LCD_D2);
  OUTPUT_OutputInit(OUT_LCD_D3);
  OUTPUT_OutputInit(OUT_LCD_RS);
  OUTPUT_OutputInit(OUT_LCD_RW);
  OUTPUT_OutputInit(OUT_LCD_EN);
  /* default login on LCD pins */
  OUTPUT_OutputSetLogic(OUT_LCD_RS,STD_LOW);
  OUTPUT_OutputSetLogic(OUT_LCD_RW,STD_LOW);
  OUTPUT_OutputSetLogic(OUT_LCD_EN,STD_LOW);
  OUTPUT_OutputSetLogic(OUT_LCD_D0,STD_HIGH);
  OUTPUT_OutputSetLogic(OUT_LCD_D1,STD_LOW);
  OUTPUT_OutputSetLogic(OUT_LCD_D2,STD_LOW);
  OUTPUT_OutputSetLogic(OUT_LCD_D3,STD_HIGH);
  /* LCD dummy */
  LCD_WriteCmd(LCD_CMD_INSTRUCT_COMP); 
  /* delay for 5ms */
  LCD_Delayms(5);
  /* LCD dummy */
  LCD_WriteCmd(LCD_CMD_INSTRUCT_COMP); 
  /* delay for 5ms */
  LCD_Delayms(5);
  /* LCD dummy */
  LCD_WriteCmd(LCD_CMD_INSTRUCT_COMP); 
  /* delay for 5ms */
  LCD_Delayms(5);
  /* set LCD 4 bit mode */
  LCD_WriteCmd(LCD_CMD_MODE_4BIT);
  /* LCD display matrix 5x8 */
  LCD_WriteCmd(LCD_CMD_LCD_5X8);
  /* disabled cursor */
  LCD_WriteCmd(LCD_CMD_CURSOR_DISABLE);
  /* clear screen */
  LCD_WriteCmd(LCD_CMD_CLRSCR);
  /* set first of top line */
  LCD_WriteCmd(LCD_CMD_LINE1);
  
}
/*******************************************************************************
** Function name: LCD_ClearScreen( void  )
** Description  : The function clear screen
** Parameter    : none
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
void LCD_ClearScreen
(
  void
)
{
  /* clear screen */
  LCD_WriteCmd(LCD_CMD_CLRSCR);
}
/*******************************************************************************
** Function name: LCD_SetCursorFirst( uint8_t line  )
** Description  : The function set cursor at first of line
** Parameter    : none
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
void LCD_SetCursorFirst
(
  uint8_t line
)
{
  switch(line)
  {
    /* line 1 */
    case 1:
      LCD_WriteCmd(LCD_CMD_LINE1);
    break;
    /* line 2 */
    case 2:
      LCD_WriteCmd(LCD_CMD_LINE2);
    break;
    /* line 3 */
    case 3:
      LCD_WriteCmd(LCD_CMD_LINE3);
    break;
    /* line 4 */
    case 4:
      LCD_WriteCmd(LCD_CMD_LINE4);
    break;
    default: break;
  }
}
/*******************************************************************************
** Function name: LCD_SetCursorPosition( uint8_t X,
**                                       uint8_t Y )
** Description  : The function set cursor at position 
** Parameter    : none
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
void LCD_SetCursorPosition
(
  uint8_t X,
  uint8_t Y
)
{
  /* check valid of line */
  if(X > 0 && X < 5)
  {
    switch(X)
    {
      /* line 1 */
      case 1:
        LCD_WriteCmd(LCD_CMD_LINE1+Y);
      break;
      /* line 2 */
      case 2:
        LCD_WriteCmd(LCD_CMD_LINE2+Y);
      break;                      
      /* line 3 */                
      case 3:                     
        LCD_WriteCmd(LCD_CMD_LINE3+Y);
      break;                      
      /* line 4 */                
      case 4:                     
        LCD_WriteCmd(LCD_CMD_LINE4+Y);
      break;
      default: break;
    }
  }
  else
  {
    /* do nothing */
  }
}
/*******************************************************************************
** Function name: LCD_WriteData( uint8_t data  )
** Description  : The function write data to LCD          
** Parameter    : data - data write to LCD
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
void LCD_WriteData
(
  uint8_t data
)
{
  uint8_t i,j;
  /* set pin RS logic high to indicates write data */
  OUTPUT_OutputSetLogic(OUT_LCD_RS,STD_HIGH);
  /* sent nibble data */
  for(j=0;j<2;j++)
  {
    /* write data to pin */
    for (i=0;i<4;i++)
    {
      if((data&MaskBit[i])>>ShiftBit[i])
      {
        switch(i)
        {
          case 0: OUTPUT_OutputSetLogic(OUT_LCD_D3,STD_HIGH);break;
          case 1: OUTPUT_OutputSetLogic(OUT_LCD_D2,STD_HIGH);break;
          case 2: OUTPUT_OutputSetLogic(OUT_LCD_D1,STD_HIGH);break;
          case 3: OUTPUT_OutputSetLogic(OUT_LCD_D0,STD_HIGH);break;
          default: break;
        }
      }
      else
      {
        switch(i)
        {
          case 0: OUTPUT_OutputSetLogic(OUT_LCD_D3,STD_LOW);break;
          case 1: OUTPUT_OutputSetLogic(OUT_LCD_D2,STD_LOW);break;
          case 2: OUTPUT_OutputSetLogic(OUT_LCD_D1,STD_LOW);break;
          case 3: OUTPUT_OutputSetLogic(OUT_LCD_D0,STD_LOW);break;
          default: break;
        }
      }
    }
    /* enable receive for LCD */
    OUTPUT_OutputSetLogic(OUT_LCD_EN,STD_HIGH);
    /* delay 1ms */
    LCD_Delayms(1); 
    /* latch data to LCD */
    OUTPUT_OutputSetLogic(OUT_LCD_EN,STD_LOW);
    /* shift to haft low of byte */
    data = data << 4;
  }
}
/*******************************************************************************
** Function name: LCD_WriteCmd( uint8_t cmd )
** Description  : The function write command to LCD          
** Parameter    : cmd - command write to LCD
** Return value : LCD_ReturnType - LCD_OK if processes success
**                                 LCD_INVALID_CMD if processes failed
** Remarks      : global variables used, side effects
*******************************************************************************/
LCD_ReturnType LCD_WriteCmd
(
  uint8_t cmd
)
{
  uint8_t i,j;
  /* set pin RS logic high to indicate write data */
  OUTPUT_OutputSetLogic(OUT_LCD_RS,STD_LOW);
  /* sent nibble of cmd */
  for(j=0;j<2;j++)
  {
    /* write cmd to pin */
    for (i=0;i<4;i++)
    {
      if((cmd&MaskBit[i])>>ShiftBit[i])
      {
        switch(i)
        {
          case 0: OUTPUT_OutputSetLogic(OUT_LCD_D3,STD_HIGH);break;
          case 1: OUTPUT_OutputSetLogic(OUT_LCD_D2,STD_HIGH);break;
          case 2: OUTPUT_OutputSetLogic(OUT_LCD_D1,STD_HIGH);break;
          case 3: OUTPUT_OutputSetLogic(OUT_LCD_D0,STD_HIGH);break;
          default: break;
        }
      }
      else
      {
        switch(i)
        {
          case 0: OUTPUT_OutputSetLogic(OUT_LCD_D3,STD_LOW);break;
          case 1: OUTPUT_OutputSetLogic(OUT_LCD_D2,STD_LOW);break;
          case 2: OUTPUT_OutputSetLogic(OUT_LCD_D1,STD_LOW);break;
          case 3: OUTPUT_OutputSetLogic(OUT_LCD_D0,STD_LOW);break;
          default: break;
        }
      }
    }
    /* enable receive for LCD */
    OUTPUT_OutputSetLogic(OUT_LCD_EN,STD_HIGH);
    /* delay 1ms */
    LCD_Delayms(3); 
    /* latch cmd to LCD */
    OUTPUT_OutputSetLogic(OUT_LCD_EN,STD_LOW);
    /* shift to haft low of byte */
    cmd = cmd << 4;
  }
	return LCD_OK;
}
/*******************************************************************************
** Function name: LCD_Printf( uint8_t* str )
** Description  : The function write string to LCD          
** Parameter    : str - string write to LCD
** Return value : none
** Remarks      : global variables used, side effects
*******************************************************************************/
void LCD_Printf
(
  uint8_t* str
)
{
  /* check null ptr */
  if(str != NULL_PTR)
  {  
    while(*str)
    {
      LCD_WriteData(*str++);
    }
  }
  else
  {
    /* do nothing */
  }  
}
/******************************************************************************
** Function name: LCD_EnableCursor()
** Description: The function enables cursor display
** Parameter X : None
** Return value: None
** Remarks: global variables used, side effects
******************************************************************************/
void LCD_EnableCursor
(
  void
)
{
  LCD_WriteCmd(LCD_CMD_CURSOR_ENABLE);
}
/******************************************************************************
** Function name: LCD_DisableCursor()
** Description: The function disables cursor display
** Parameter X : None
** Return value: None
** Remarks: global variables used, side effects
******************************************************************************/
void LCD_DisableCursor
(
  void
)
{
  LCD_WriteCmd(LCD_CMD_CURSOR_DISABLE);
}
/*****************************************************************************/
/* End Of File Copyright LINDBOARD 2014                                      */
/*****************************************************************************/
